package entity

import (
	"fmt"
	"time"

	"gorm.io/gorm"
	"shqsoft.cn/pas3ui/base"
)

//对私储蓄存款认定分户情况
type IndiAccoPl struct {
	ID    int       `gorm:"AUTO_INCREMENT;primary_key;column:ID"`
	IDNO  string    `gorm:"column:IDNO"`
	CDNO  string    `gorm:"column:CDNO"`
	ACNO  string    `gorm:"column:ACNO"`
	BANO  string    `gorm:"column:BANO"`
	KHMC  string    `gorm:"column:KHMC"`
	EMID1 *int      `gorm:"column:EMID1"`
	EMNO1 string    `gorm:"column:EMNO1"`
	ZB1   float64   `gorm:"column:ZB1"`
	EMID2 *int      `gorm:"column:EMID2"`
	EMNO2 string    `gorm:"column:EMNO2"`
	ZB2   float64   `gorm:"column:ZB2"`
	EMID3 *int      `gorm:"column:EMID3"`
	EMNO3 string    `gorm:"column:EMNO3"`
	ZB3   float64   `gorm:"column:ZB3"`
	DSDT  time.Time `gorm:"column:DSDT"` //分户日期
	DSEM  *int      `gorm:"column:DSEM"`
}

//TableName 对私储蓄存款认定分户情况
func (IndiAccoPl) TableName() string {
	return "T_INDI_ACCO_PL"
}
func (i *IndiAccoPl) AfterFind(tx *gorm.DB) (err error) {
	i.ACNO = base.CdnoTM(i.ACNO)
	i.BANO = base.AcnoTM(i.BANO)
	i.CDNO = base.CdnoTM(i.CDNO)
	return
}

type IndiAccoPlCard struct {
	ACID int `gorm:"AUTO_INCREMENT;primary_key;column:ACID"`
	CDNO int `gorm:"column:CDNO"`
}

func (IndiAccoPlCard) TableName() string {
	return "T_INDI_ACCO_PL_CARD"
}

func (i *IndiAccoPl) BeforeSave(tx *gorm.DB) (err error) {
	bdate, err := base.GetBackDATE("shls")
	if err != nil {
		return
	}
	if i.DSDT.Unix() < bdate.Unix() {
		err = fmt.Errorf("分户日期不能小于最早可追溯日期，最大追溯日期为【" + bdate.Format("2006-01-02") + "】")
		return
	}
	var count int
	base.CHDB.Raw("SELECT COUNT(*) FROM T_INDI_CARD WHERE card_no = ?", i.CDNO).Row().Scan(&count)
	if count == 0 {
		err = fmt.Errorf("卡号:%s在系统中不存在！", i.CDNO)
		return
	}
	//判断是否重复导入
	if i.ID == 0 {
		tx.Raw(`SELECT COUNT(*) FROM "T_INDI_ACCO_PL" WHERE "CDNO"=?`, i.CDNO).Row().Scan(&count)
		if count > 0 {
			err = fmt.Errorf("卡号:%s,不能重复导入！", i.CDNO)
			return
		}
	}
	sum := i.ZB1 + i.ZB2 + i.ZB3
	if sum != 100 {
		err = fmt.Errorf("占比之和必须为100！")
		return
	}
	sqlStr := `SELECT "ID" FROM "T_SysUser" WHERE "SysUserID" =?`
	err = tx.Raw(sqlStr, i.EMNO1).Row().Scan(&i.EMID1)
	if err != nil {
		err = fmt.Errorf("员工工号1:%s在系统中没有找到！", i.EMNO1)
		return
	}
	if i.ZB2 > 0 {
		tx.Raw(sqlStr, i.EMNO2).Row().Scan(&i.EMID2)
		if err != nil {
			err = fmt.Errorf("员工工号2:%s在系统中没有找到！", i.EMNO2)
			return
		}
	}
	if i.ZB3 > 0 {
		tx.Raw(sqlStr, i.EMNO3).Row().Scan(&i.EMID3)
		if err != nil {
			err = fmt.Errorf("员工工号3:%s在系统中没有找到！", i.EMNO3)
			return
		}
	}
	rows, err := base.CHDB.Raw(`SELECT "ID","CDNO" FROM "T_INDI_ACCO" WHERE "CDNO" = ?`, i.CDNO).Rows()
	if err != nil {
		return err
	}
	defer rows.Close()
	for rows.Next() {
		var acid, cdno int
		if err = rows.Scan(&acid, &cdno); err != nil {
			return err
		}
		card := IndiAccoPlCard{
			ACID: acid,
			CDNO: cdno,
		}
		err = tx.Save(&card).Error
		if err != nil {
			return
		}
	}
	return
}

//IndiAccoAfterImport 导入后执行分户处理
func IndiAccoAfterImport(tx *gorm.DB, params map[string]string) (err error) {
	var sqlstr string
	if base.AppConf.Database.Mysql != "" {
		sqlstr = `UPDATE T_INDI_ACCO_DIVI A,T_INDI_ACCO_PL B,T_INDI_ACCO_PL_CARD C
		SET WODT=B.DSDT,ISWO=CASE WHEN A.DSDT<B.DSDT THEN 0 ELSE 1 END
		WHERE A.ACID=C.ACID AND B.CDNO=C.CDNO AND A.ISWO=0 AND (A.WODT IS NULL OR A.WODT>B.DSDT)`
	} else {
		sqlstr = `UPDATE "T_INDI_ACCO_DIVI" A SET "WODT"=B."DSDT","ISWO"=CASE WHEN A."DSDT"<B."DSDT" THEN 0 ELSE 1 END
		from "T_INDI_ACCO_PL" B,"T_INDI_ACCO_PL_CARD" C
		WHERE A."ACID"=C."ACID" and B."CDNO"=C."CDNO" AND A."ISWO"=0 AND (A."WODT" IS NULL OR A."WODT">B."DSDT")`
	}
	err = tx.Exec(sqlstr).Error
	if err != nil {
		tx.Rollback()
		return
	}
	sqlstr = `INSERT INTO T_INDI_ACCO_DIVI(ACID,EMID,DSVL,DSDT,DSEM)
	SELECT DISTINCT "ACID","EMID","DSVL","DSDT","DSEM" 
	FROM (SELECT "ACID","EMID1" "EMID",ZB1/100 "DSVL","DSDT","DSEM" FROM "T_INDI_ACCO_PL" A INNER JOIN "T_INDI_ACCO_PL_CARD" B ON A."CDNO"=B."CDNO"
	UNION ALL
	SELECT "ACID","EMID2" "EMID","ZB2"/100 "DSVL","DSDT","DSEM" FROM "T_INDI_ACCO_PL" A INNER JOIN "T_INDI_ACCO_PL_CARD" B ON A."CDNO"=B."CDNO"
	WHERE "EMID2" IS NOT NULL
	UNION ALL
	SELECT "ACID","EMID3" "EMID","ZB3"/100 "DSVL","DSDT","DSEM" FROM "T_INDI_ACCO_PL" A INNER JOIN "T_INDI_ACCO_PL_CARD" B ON A."CDNO"=B."CDNO"
	WHERE "EMID3" IS NOT NULL) A`
	err = tx.Exec(sqlstr).Error
	if err != nil {
		tx.Rollback()
		return
	}
	err = tx.Exec(`TRUNCATE TABLE "T_INDI_ACCO_PL_CARD"`).Error
	if err != nil {
		tx.Rollback()
		return
	}
	tx.Commit()
	return
}

func IndiAccoPlEF() base.EntityFunc {
	return func() interface{} {
		entity := IndiAccoPl{}
		return &entity
	}
}
func IndiAccoPlESF() base.EntitiesFunc {
	return func() interface{} {
		var entities []IndiAccoPl
		return &entities
	}
}

func init() {
	base.DaoPoolObj.Put("IndiAccoPl", base.NewDefaultDao(IndiAccoPlEF(), IndiAccoPlESF(), nil, "my"))
	base.SetAfterCallBack("IndiAccoPl", IndiAccoAfterImport)
}
